﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GemTowerDefence
{
  public class Enemy : Sprite
  {
    private readonly Queue<Vector2> _waypoints = new Queue<Vector2>();

    private readonly float _startHealth;
    private readonly float _speed = 0.5F;

    private bool _alive = true;
    private double _modiferCurrentTime;


    public float CurrentHealth { get; set; }

    public bool IsDead
    {
      get { return CurrentHealth <= 0 || !_alive; }
    }

    public int BountyGiven { get; private set; }

    public float DistanceToDestination
    {
      get
      {
        return _waypoints.Count == 0 ? 0 : Vector2.Distance(Position, _waypoints.Peek());
      }
    }

    public int WaypointCount
    {
      get { return _waypoints.Count; }
    }

    public float SpeedModifier { get; set; }

    public float ModifierDuration { get; set; }

    public float HealthPercentage
    {
      get { return CurrentHealth / _startHealth; }
    }

    public Enemy(Texture2D texture, Vector2 position, float health, int bountyGiven, float speed)
      : base(texture, position)
    {
      _startHealth = health;
      CurrentHealth = _startHealth;
      BountyGiven = bountyGiven;
      _speed = speed;
    }

    public void SetWaypoints(Queue<Vector2> waypoints)
    {
      foreach (var waypoint in waypoints)
        _waypoints.Enqueue(waypoint);

      Position = _waypoints.Dequeue();
    }

    public override void Update(GameTime gameTime)
    {
      base.Update(gameTime);

      if (_waypoints.Count > 0 && _alive)
      {
        if (DistanceToDestination < 1.1f)
        {
          Position = _waypoints.Peek();
          _waypoints.Dequeue();
        }

        else
        {
          var direction = _waypoints.Peek() - Position;
          direction.Normalize();

          // Store the original speed.
          float temporarySpeed = _speed;

          // If the modifier has finished,
          if (_modiferCurrentTime > ModifierDuration)
          {
            // reset the modifier.
            SpeedModifier = 0;
            _modiferCurrentTime = 0;
          }

          if (Math.Abs(SpeedModifier - 0) > double.Epsilon && _modiferCurrentTime <= ModifierDuration)
          {
            // Modify the speed of the enemy.
            temporarySpeed *= SpeedModifier;
            // Update the modifier timer.
            _modiferCurrentTime += gameTime.ElapsedGameTime.TotalSeconds;
          }

          Velocity = Vector2.Multiply(direction, temporarySpeed);

          Position += Velocity;
        }
      }

      else
        _alive = false;

      if (CurrentHealth <= 0)
        _alive = false;
    }

    public override void Draw(SpriteBatch spriteBatch)
    {
      if (_alive)
      {
        var healthPercentage = CurrentHealth / _startHealth;
        var color = new Color(new Vector3(1 - healthPercentage, 1 - healthPercentage, 1 - healthPercentage));

        base.Draw(spriteBatch, color);
      }
    }

  }
}
